#include "ConnectRequest.h"


ConnectRequest::ConnectRequest(void)
{
	m_nAR = 0;
	memset(m_cUser, 0, ConReqEnum::USERBUF + 1);
	memset(m_cPassword, 0, ConReqEnum::USERBUF + 1);
	memset(&m_kSockAddr, 0, sizeof(m_kSockAddr));

	WSADATA wsdata;
	if(WSAStartup(MAKEWORD(2,2), &wsdata) != 0)
		AfxMessageBox("WS2_32.DLL Initiate Failed");
}


ConnectRequest::~ConnectRequest(void)
{
}

bool ConnectRequest::Connect(HWND m_hWnd, char *host, char *port)
{
	m_nConn = socket(AF_INET, SOCK_STREAM, 0);
	if (m_nConn == INVALID_SOCKET)
	{
		AfxMessageBox("socket() error");
	}
	strncpy_s(m_cIP, CustomBuf::SYNBUFSIZE, host, 16);
	m_kSockAddr.sin_family = AF_INET;
	m_kSockAddr.sin_addr.s_addr = inet_addr(host);
	m_kSockAddr.sin_port = htons(atoi(port));
	if (connect(m_nConn, (SOCKADDR*)&m_kSockAddr, sizeof(m_kSockAddr)) == SOCKET_ERROR)
	{
		AfxMessageBox("connect() failed");
		return false;
	}
	WSAAsyncSelect(m_nConn, m_hWnd, WM_USER_SOCKET, FD_READ|FD_CLOSE);

	return true;
}

void ConnectRequest::SetUser(char *user, UINT len)
{
	strncpy_s(m_cUser, user, len);
}

void ConnectRequest::SetPassword(char *password, UINT len)
{
	strncpy_s(m_cPassword, password, len);
}

int ConnectRequest::ResponseAnalysis(void)
{
	m_pcCopyParse = m_cCopyBuf;

	switch (*m_pcCopyParse)
	{
	case '1':
		if (m_nState == m_kConState::CONNECT)
		{
			m_nState = m_kConState::CONNECT_WAIT;
		}
		break;

	case '2':
		m_nAR = AutoRequest();
		return m_nAR;

	case '3':
		if (m_nState == m_kConState::USER)
		{
			sprintf_s(m_cSendBuf, CustomBuf::SYNBUFSIZE, "PASS %s\r\n", m_cPassword);
			send(m_nConn, m_cSendBuf, strlen(m_cSendBuf), 0);
			m_nState = m_kConState::PASS;
		}
		break;

	case '4':
		//make Data connection failed handle
		if (m_nState == m_kConState::NONE)
		{
			return m_kConState::DISCONNECT;
		}
		m_nState = 0;
		AfxMessageBox(m_cCopyBuf);
		break;

	case '5':
		//make Data connection failed handle
		if (m_nState == m_kConState::SYST)
		{
			if (atoi(m_pcCopyParse) != 220)
			{
				memset(m_cSendBuf, 0, sizeof(m_cSendBuf));
				sprintf(m_cSendBuf, "USER %s\r\n", m_cUser);

				send(m_nConn, m_cSendBuf, strlen(m_cSendBuf), 0);

				m_nState = m_kConState::USER;
			}
			break;
		}
		m_nState = 0;
		AfxMessageBox(m_cCopyBuf);
		break;
	}
	return 0;
}

int ConnectRequest::AutoRequest(void)
{
	if (m_nState == m_kConState::CONNECT || m_nState == m_kConState::CONNECT_WAIT)
	{
		send(m_nConn, "SYST\r\n", 6, 0);
		m_nState = m_kConState::SYST;
	}
	else if (m_nState == m_kConState::SYST)
	{
		if (atoi(m_pcCopyParse) != 220)
		{
			memset(m_cSendBuf, 0, sizeof(m_cSendBuf));
			sprintf(m_cSendBuf, "USER %s\r\n", m_cUser);

			send(m_nConn, m_cSendBuf, strlen(m_cSendBuf), 0);

			m_nState = m_kConState::USER;
			m_pcCopyParse += 4;
			if (*m_pcCopyParse == 'W')
			{
				return m_kConState::SAMEOS;
			}
			else
			{
				return m_kConState::DIFFOS;
			}
		}
	}
	else if (m_nState == m_kConState::USER || m_nState == m_kConState::PASS)
	{
		send(m_nConn, "PWD\r\n", 5, 0);
		m_nState = m_kConState::PWD;
	}
	else if (m_nState == m_kConState::PWD)
	{
		ResponsePWD();
		m_nState = m_kConState::PASV;
	}
	else if (m_nState == m_kConState::PASV)
	{
		ResponsePASV();
		CreateDataConn();
		PutItemList();
		m_nState = m_kConState::NONE;
		return m_kConState::PASV;
	}
	return 0;
}

void ConnectRequest::ResponsePWD(void)
{
	RequestHandle::ResponsePWD();
	send(m_nConn, "PASV\r\n", 6, 0);
}